package com.pe.pgn.clubpgn.dao.impl;

import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.hibernate.Criteria;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import com.pe.pgn.clubpgn.common.CLPConstantes;
import com.pe.pgn.clubpgn.dao.UnidadMedidaDao;
import com.pe.pgn.clubpgn.dao.hibernate.GenericDaoHibernate;
import com.pe.pgn.clubpgn.domain.ClpdUnidadMedida;

@Repository
public class UnidadMedidaDaoImpl extends GenericDaoHibernate<ClpdUnidadMedida, Long> implements
		UnidadMedidaDao {

	private JdbcTemplate jdbcTemplate;
	
	@Autowired
	public void setDataSource(DataSource dataSource) {
		this.jdbcTemplate = new JdbcTemplate(dataSource);
	}
	
	public UnidadMedidaDaoImpl(){
		super(ClpdUnidadMedida.class);
	}
	
	@SuppressWarnings("unchecked")
	public Map guardarUnidadMedida(ClpdUnidadMedida unidadMedida){
		
		Map mapMsg = new HashMap();
		Long idUnidadMedida = unidadMedida.getId();
		boolean stUnidadMedida = unidadMedida.isStUnidadMedida();
		boolean stIndicadorPuntos = unidadMedida.isStIndicadorPuntos();
		
		//la validacion solo aplica para registros activos
		if(stUnidadMedida){
			
			int conteo = validaSoloExistaUnIndParaPtos(idUnidadMedida,
			stIndicadorPuntos);
			
			if(stIndicadorPuntos && conteo > 0){			
				mapMsg.put(CLPConstantes.MSG, CLPConstantes.ERROR);
				mapMsg.put("detalle", "Ya existe un registro activo marcado como indicador para puntos.");			
				return mapMsg;
			}
		}
		
		if(idUnidadMedida == null){
			unidadMedida.setCoUsuarioCreador(getUsuarioLogueado().getUsername());
			unidadMedida.setDaFechaCreacion(Calendar.getInstance());
		}
		else{
			unidadMedida.setCoUsuarioModificador(getUsuarioLogueado().getUsername());
			unidadMedida.setDaFechaModificacion(Calendar.getInstance());
		}	
		
		getHibernateTemplate().saveOrUpdate(unidadMedida);
		getHibernateTemplate().flush();
		
		mapMsg.put(CLPConstantes.MSG, CLPConstantes.SUCCESS);
		return mapMsg;
	}
	
	private int validaSoloExistaUnIndParaPtos(Long idUnidadMedida,
			boolean stIndicadorPuntos) {

		StringBuffer query = new StringBuffer();
		query.append(" select ");
		query.append(" count(id) ");
		query.append(" from clpd_unidad_medida ");
		query.append(" where st_indicador_puntos = '"+CLPConstantes.ST_VERDADERO+"'");
		query.append(" and st_unidad_medida = '"+CLPConstantes.ST_VERDADERO+"'");
		
		if(idUnidadMedida != null)
		query.append(" and id != ").append(idUnidadMedida);
		
		return jdbcTemplate.queryForInt(query.toString());
	}
	
	public ClpdUnidadMedida obtenerUnidadMedida(Long id){
		
		ClpdUnidadMedida unidadMedida = get(id);
		return unidadMedida;
	}
	
	public void eliminarUnidadMedida(Long id){
		
		remove(id);
		getHibernateTemplate().flush();
	}
	
	@SuppressWarnings("unchecked")
	public List<ClpdUnidadMedida> obtenerUnidadesMedida(){
		
		Criteria criteria = DetachedCriteria.forClass(ClpdUnidadMedida.class)
		.getExecutableCriteria(getSessionFactory().getCurrentSession());

		criteria.setMaxResults(CLPConstantes.MAXIMO_RESULTADO_INICIAL);
		criteria.addOrder(Order.desc("id"));
		
		List<ClpdUnidadMedida> lista = criteria.list(); 
		return lista;
	}
	
	
}
